import {
  Body,
  ClassSerializerInterceptor,
  Controller,
  Delete,
  Get,
  Param,
  Post,
  Put,
  Query,
  Res,
  UseInterceptors
} from '@nestjs/common'
import dayjs from 'dayjs'
import ExcelJS from 'exceljs'
import { ApiTags } from '@nestjs/swagger'
import { ApiAuth } from '@/common/decorators'
import { UserService } from './user.service'
import { ICRUD, IResponse } from '@/common/interfaces'
import {
  CreateUserDTO,
  DeleteUsersDTO,
  FindUserDTO,
  PaginateUserDTO,
  UpdateUserDTO
} from './dtos'
import { PaginateSerialize, UserSerialize } from './serializes'

@ApiAuth()
@ApiTags('UserController')
@Controller('/user')
export class UserController implements ICRUD {
  constructor(private userService: UserService) {}

  @Get('/one')
  @UseInterceptors(ClassSerializerInterceptor)
  async findOne(@Query() query: FindUserDTO) {
    const data = await this.userService.findOne(query)
    return new UserSerialize(data)
  }

  @Get('/list')
  @UseInterceptors(ClassSerializerInterceptor)
  async findMany(@Query() query: FindUserDTO) {
    const data = await this.userService.findMany(query)
    return data.map(item => new UserSerialize(item))
  }

  @Get('/paginate')
  @UseInterceptors(ClassSerializerInterceptor)
  async paginate(@Query() dto: PaginateUserDTO) {
    const data = await this.userService.paginate(dto)
    return new PaginateSerialize(data)
  }

  @Post('/one')
  async createOne(@Body() dto: CreateUserDTO) {
    await this.userService.createOne(dto)
    return null
  }

  @Put('/one/:id')
  async updateOne(@Param('id') id: number, @Body() dto: UpdateUserDTO) {
    await this.userService.updateOne(id, dto)
    return null
  }

  @Delete('/one/:id')
  async deleteOne(@Param('id') id: number) {
    await this.userService.deleteOne(id)
    return null
  }

  @Delete('/list')
  async deleteMany(@Body() dto: DeleteUsersDTO) {
    await this.userService.deleteMany(dto.ids)
    return null
  }

  @Get('/export')
  async exportExcel(@Query() dto: FindUserDTO, @Res() res: IResponse) {
    const data = await this.userService.findMany(dto)
    const wb = new ExcelJS.Workbook()
    const ws = wb.addWorksheet('User')
    ws.columns = [
      { header: '记录编号', key: 'id', width: 10 },
      { header: '用户编号', key: 'userId', width: 40 },
      { header: '用户名', key: 'username', width: 20 },
      { header: '性别', key: 'gender', width: 20 },
      { header: '年龄', key: 'age', width: 10 },
      { header: '手机号', key: 'mobile', width: 20 },
      { header: '创建时间', key: 'createAt', width: 20 }
    ]
    ws.addRows(data)
    const buffer = await wb.xlsx.writeBuffer()
    res
      .set({
        'Content-Type': 'application/vnd.openxmlformats;charset=utf-8',
        'Content-Disposition': `attachment; filename=${dayjs().format(
          'YYYYMMDDHHmmss'
        )}.xlsx`
      })
      .end(buffer)
  }
}
